package com.sky.es.service.impl;

import com.sky.es.api.request.CreateProductDocReuqest;
import com.sky.es.entity.ProductDoc;
import com.sky.es.esDataRepository.ElasticsearchDaoRepository;
import com.sky.es.service.ProductEsService;
import com.sky.es.util.StringCovertDouble;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yangsk
 */
@Service
@Slf4j
public class ProductEsServiceImpl implements ProductEsService {
   @Autowired
    private ElasticsearchRestTemplate esTemplate;
    
   @Autowired
   private ElasticsearchDaoRepository esRepository;


    @Override
    public void createProductDoc(CreateProductDocReuqest request) {
        ProductDoc productDoc = new ProductDoc();
        BeanUtils.copyProperties(request,productDoc);
        Date date = new Date();
        productDoc.setCreateTime(date);
        productDoc.setUpdateTime(date);
        Double longitude = StringCovertDouble.convertToDouble(request.getLongitude());//Double.parseDouble(request.getLongitude());
        Double latitude = StringCovertDouble.convertToDouble(request.getLatitude());
        productDoc.setLocation(new GeoPoint(longitude,latitude));
        ProductDoc save = esRepository.save(productDoc);
        log.info("向ES添加商品文档：{}",save);
    }

    @Override
    public ProductDoc findById(Long id) {
        log.info("商品文档id：{}",id);
        Optional<ProductDoc> optionProductDoc = esRepository.findById(id);
        ProductDoc productDoc = optionProductDoc.get();
        log.info("根据商品文档id查询es的文档结果：{}",productDoc);
        return productDoc;
    }

    @Override
    public List<ProductDoc> findByName(String name) {
        List<ProductDoc> lsit = esRepository.findByName(name);
        return lsit;
    }

    @Override
    public List<ProductDoc> getTermQueryByType(String type) {
        TermQueryBuilder termQuery = QueryBuilders.termQuery("type.keyword",type);
        NativeSearchQuery nsquery = new NativeSearchQueryBuilder().withQuery(termQuery).build();
        SearchHits<ProductDoc> searchResult = esTemplate.search(nsquery, ProductDoc.class);
        List<SearchHit<ProductDoc>> searchHits = searchResult.getSearchHits();
        List<ProductDoc> resultList = new ArrayList<>();
        //组装数据并返回
        /*for(SearchHit<ProductDoc> list:searchHits){
            resultList.add(list.getContent());
        }
        return resultList;*/
        return searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
    }

    @Override
    public List<ProductDoc> getTermsQueryByPrice(Long  onePrice,Long twoPrice) {
        //TermsQueryBuilder termsQuery = QueryBuilders.termsQuery("price", onePrice, twoPrice);
        TermsQueryBuilder query = QueryBuilders.termsQuery("price",new long[]{onePrice,twoPrice});
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).build();
        SearchHits<ProductDoc> queryResult = esTemplate.search(searchQuery, ProductDoc.class);
        if(null != queryResult && !CollectionUtils.isEmpty(queryResult.getSearchHits())){
            return queryResult.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    @Override
    public List<ProductDoc> getRnageQueryByPrice(Long onwPrice, Long twoPrice) {
        //组装range的范围查询条件
        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("price");
        rangeQuery.gte(onwPrice);
        rangeQuery.lte(twoPrice);
        //组装查询对象
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(rangeQuery).build();
        SearchHits<ProductDoc> queryResult = esTemplate.search(searchQuery, ProductDoc.class);
        if(null != queryResult && !CollectionUtils.isEmpty(queryResult.getSearchHits())){
            return queryResult.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    @Override
    public List<ProductDoc> getMatchQueryByName(String name) {
        MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("name", name);
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery).build();
        SearchHits<ProductDoc> queryResult = esTemplate.search(searchQuery, ProductDoc.class);
        if(null != queryResult && !CollectionUtils.isEmpty(queryResult.getSearchHits())){
            return queryResult.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    @Override
    public List<ProductDoc> getMultiMatchQueryByConditioin(String condition) {
        MultiMatchQueryBuilder multiMatchQuer = QueryBuilders.multiMatchQuery(condition, new String[]{"name", "tages"});
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(multiMatchQuer).build();
        SearchHits<ProductDoc> queryResult = esTemplate.search(searchQuery, ProductDoc.class);
        if(null != queryResult && !CollectionUtils.isEmpty(queryResult.getSearchHits())){
            return queryResult.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    @Override
    public List<ProductDoc> getMatchAllQuery() {
        MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery).build();
        SearchHits<ProductDoc> queryResult = esTemplate.search(searchQuery, ProductDoc.class);
        if(null != queryResult && !CollectionUtils.isEmpty(queryResult.getSearchHits())){
            return queryResult.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    @Override
    public List<ProductDoc> getMatchPhrase(String condition) {
        MatchPhraseQueryBuilder mutchPhraseQuery = QueryBuilders.matchPhraseQuery("desc", condition);
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(mutchPhraseQuery).build();
        SearchHits<ProductDoc> queryResult = esTemplate.search(searchQuery, ProductDoc.class);
        if(null != queryResult && !CollectionUtils.isEmpty(queryResult.getSearchHits())){
            return queryResult.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    @Override
    public List<ProductDoc> getMustByPrice(Long price) {
        return Collections.emptyList();
    }
}
